package com.traveldream.testing;

import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;

import com.traveldream.entities.DefaultPacket;
import com.traveldream.entities.Packet;
import com.traveldream.entity_managers.PacketManager;

@ManagedBean(name="packet_manager_test")
@SessionScoped
public class PacketManagerTest implements TestingTravelDream {
	@EJB
	private PacketManager pm;

	@ManagedProperty(value="#{test_bean}")
	private TestBean testBean;
	
	private String log;
	private StringBuilder logSb;
	
	// i test avvengono su variabili defaultPacket
	// per la entity customPacket i metodi sono duali

	@Override
	public void runTests() {
		logSb=new StringBuilder(300);
		logSb.append("******** TESTING DEL SESSION BEAN: PACKET MANAGER *******");logSb.append(System.lineSeparator());
		logSb.append("***** INIZIO TESTING *****");	logSb.append(System.lineSeparator());
		addTest();
		logSb.append(System.lineSeparator());
		addDeleteTest();
		logSb.append(System.lineSeparator());
		updateTest();
		logSb.append(System.lineSeparator());
		findByParametersTest();
		logSb.append(System.lineSeparator());
		this.log=logSb.toString();
		System.out.print(this.log);
		testBean.setProd(false); testBean.setPack(true); testBean.setBook(false);	testBean.setInv(false);
	}
	
	@Override
	public void addTest() {
		logSb.append("*** ADD TEST PACKET MANAGER ***");logSb.append(System.lineSeparator());
		//view initial state
		List<DefaultPacket> initialState=pm.findAllDefaultPackets();
		logSb.append("> INITIAL STATE: {");
		for( DefaultPacket e: initialState )
			logSb.append("   "+e.getPacketId());
		logSb.append("   }");
		logSb.append(System.lineSeparator());
		//add new packet
		Packet p=new Packet();
		DefaultPacket nuova=new DefaultPacket();	nuova.setPacket(p);	
		logSb.append("> NEW PACKET CREATED");	logSb.append(System.lineSeparator());
		DefaultPacket nn=pm.create(nuova);
		logSb.append("> NEW PACKET ADDED id = "+nn.getPacketId());logSb.append(System.lineSeparator());
		//view final state
		List<DefaultPacket> finalState=pm.findAllDefaultPackets();
		logSb.append("> FINAL STATE: {");
		for( DefaultPacket e: finalState )
			logSb.append("   "+e.getPacketId());
		logSb.append("   }");
		logSb.append(System.lineSeparator());
		initialState.add(nn);
		Comparator<DefaultPacket>comp=new Comparator<DefaultPacket>() {
			@Override
			public int compare(DefaultPacket o1, DefaultPacket o2) {
				return o1.getPacketId()-o2.getPacketId();
			}			
		};
		Collections.sort(initialState,comp);
		Collections.sort(finalState,comp);
		if( initialState.equals(finalState) )
			logSb.append(" *** TEST PERFORMED SUCCESSFULLY *** ");
		else
			logSb.append(" *** TEST FAILURE *** ");
		logSb.append(System.lineSeparator());
		logSb.append(" *** END ADD TEST ***");logSb.append(System.lineSeparator());
	}

	@Override
	public void deleteTest() {
		// non � prevista dal sistema l'eliminazione di pacchetti
	}

	@Override
	public void addDeleteTest() {
		logSb.append("*** ADD-DELETE TEST PACKET MANAGER ***");logSb.append(System.lineSeparator());
		//visualize initial state
		List<DefaultPacket> initialState=pm.findAllDefaultPackets();
		logSb.append("> INITIAL STATE: {");
		for( DefaultPacket e: initialState )
			logSb.append("   "+e.getPacketId());
		logSb.append("   }");
		logSb.append(System.lineSeparator());
		// add new default packet
		Packet p=new Packet();
		DefaultPacket nuova=new DefaultPacket();	nuova.setPacket(p);	
		logSb.append("> NEW PACKET CREATED");	logSb.append(System.lineSeparator());
		int id=pm.create(nuova).getPacketId();
		logSb.append("> NEW PACKET ADDED id = "+id); logSb.append(System.lineSeparator());
		//visualize intermediate state
		List<DefaultPacket> intermediateState=pm.findAllDefaultPackets();
		logSb.append("> INTERMEDIATE STATE: {");
		for( DefaultPacket e: intermediateState )
			logSb.append("   "+e.getPacketId());
		logSb.append("   }");
		logSb.append(System.lineSeparator());
		//delete the same packet
		pm.delete(id);
		logSb.append("> PACKET DELETED: id = "+id);logSb.append(System.lineSeparator());
		//visualize the final state
		List<DefaultPacket> finalState=pm.findAllDefaultPackets();
		logSb.append("> FINAL STATE: {");
		for( DefaultPacket e: finalState )
			logSb.append("   "+e.getPacketId());
		logSb.append("   }");logSb.append(System.lineSeparator());
		//sort lists
		Comparator<DefaultPacket> comp=new Comparator<DefaultPacket>() {
			public int compare(DefaultPacket e1, DefaultPacket e2) { 
				return e1.getPacketId()-e2.getPacketId();
			}
		};
		Collections.sort(initialState,comp);
		Collections.sort(finalState,comp);
		//check if inital and final states are equals
		if( initialState.equals(finalState) )
			logSb.append(" *** TEST PERFORMED SUCCESSFULLY *** ");
		else
			logSb.append(" *** TEST FAILURE *** ");
		logSb.append(System.lineSeparator());
		logSb.append(" *** END ADD-DELETE TEST ***");	logSb.append(System.lineSeparator());
	}

	@Override
	public void updateTest() {
		logSb.append("*** UPDATE TEST PACKET MANAGER ***");logSb.append(System.lineSeparator());
		//visualize initial state
		List<DefaultPacket> initialState=pm.findAllDefaultPackets();
		logSb.append("> INITIAL STATE: {");
		for( DefaultPacket e: initialState )
			logSb.append("   "+e.getPacketId());
		logSb.append("   }");
		logSb.append(System.lineSeparator());
		//create new excursion with name = before
		Packet p=new Packet();
		DefaultPacket e=new DefaultPacket();
		p.setName("before"); p.setDescription("packet created for testing");
		e.setPacket(p);
		DefaultPacket before=pm.create(e);
		int id=before.getPacketId();
		logSb.append("> PACKET ADDED: id = "+id+", name = "+before.getPacket().getName()+", description = "+before.getPacket().getDescription());
		logSb.append(System.lineSeparator());
		//modify the object and update it
		p.setName("after"); p.setDescription("packet modified for testing");
		before.setPacket(p);
		pm.update(before);
		logSb.append("> PACKET UPDATED ");logSb.append(System.lineSeparator());
		DefaultPacket after=pm.findDefaultPacket(id);
		logSb.append("> PACKET TAKEN FROM DB");logSb.append(System.lineSeparator());
		logSb.append("> PACKET UPDATED: id = "+id+", name = "+after.getPacket().getName()+", description = "+after.getPacket().getDescription());
		logSb.append(System.lineSeparator());
		if( before.getPacket().getName().equals(after.getPacket().getName()) && before.getPacket().getDescription().equals(after.getPacket().getDescription()) )
			logSb.append(" *** TEST PERFORMED SUCCESSFULLY");
		else
			logSb.append(" *** TEST FAILURE *** ");
		logSb.append(System.lineSeparator());
		logSb.append(" *** END UPDATE TEST ***");	logSb.append(System.lineSeparator());
	}

	@SuppressWarnings("deprecation")
	@Override
	public void findByParametersTest() {
		logSb.append("*** FIND TEST PACKET MANAGER ***");logSb.append(System.lineSeparator());
		//visualize initial state
		List<DefaultPacket> initialState=pm.findAllDefaultPackets();
		logSb.append("> INITIAL STATE: {");
		for( DefaultPacket e: initialState )
			logSb.append("   "+e.getPacketId());
		logSb.append("   }");
		logSb.append(System.lineSeparator());
		//create new default packet with name = new, starting_date = 30/01/2014, final_date = 07/02/2014
		Packet p=new Packet();
		GregorianCalendar in=new GregorianCalendar(2014,GregorianCalendar.JANUARY,30);
		GregorianCalendar fin=new GregorianCalendar(2014,GregorianCalendar.FEBRUARY,7);
		p.setName("new"); p.setDescription("packet created for testing");
		Date inDate=in.getTime(); Date finDate=fin.getTime();
		p.setStartingDate(inDate);	p.setEndingDate(finDate);
		DefaultPacket e=new DefaultPacket();
		e.setPacket(p);
		DefaultPacket nuova=pm.create(e);
		int id=nuova.getPacketId();
		logSb.append("> PACKET ADDED: id = "+id+", name = "+nuova.getPacket().getName()+", description = "+nuova.getPacket().getDescription()+", "
				+ "starting date = "+in.getTime().toLocaleString()+", ending date = "+fin.getTime().toLocaleString());
		logSb.append(System.lineSeparator());
		//find the object
		GregorianCalendar param1=new GregorianCalendar(2014,GregorianCalendar.JANUARY,28);
		GregorianCalendar param2=new GregorianCalendar(2014,GregorianCalendar.FEBRUARY,8);
		List<DefaultPacket> query=pm.findByDates(param1.getTime(),param2.getTime());
		logSb.append("> QUERY EXECUTED: find default packets between "+param1.getTime().toLocaleString()+" and "+param2.getTime().toLocaleString());
		logSb.append(System.lineSeparator());
		//visualize results
		boolean found=false;
		logSb.append("> QUERY RESULTS: {");
			for( DefaultPacket x: query ) {
				if( x.getPacketId()==id ) found=true;
				logSb.append("   "+x.getPacketId());
			}
			logSb.append("   }");
			logSb.append(System.lineSeparator());
		if( found )
			logSb.append(" *** TEST PERFORMED SUCCESSFULLY");
		else
			logSb.append(" *** TEST FAILURE *** ");
		logSb.append(System.lineSeparator());
		logSb.append(" *** END FIND TEST ***");	logSb.append(System.lineSeparator());
	}
	
	public TestBean getTestBean() {
		return testBean;
	}

	public void setTestBean(TestBean testBean) {
		this.testBean = testBean;
	}

	public void setLog(String log) {
		this.log = log;
	}

	public String getLog() {
		return log;
	}

}
